package vg.modules.util_plugins;

import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Observable;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.skin.SkinInfo;

import vg.services.main_manager.MainManager;
import vg.services.plugin_manager.event_and_request.event.UIEventChangeUIStyle;
import vg.services.plugin_manager.interfaces.IPlugin;
import vg.services.plugin_manager.realization.PluginParameter;
import vg.services.user_interface_manager.interfaces.AMenuItem;

public class LookAndFeelChanger implements IPlugin {
	private PluginParameter param;
	public static final String CONF_STYLE = "L&FStyle";
	private Map<String, SkinInfo> skins;
	@Override
	public void install(final PluginParameter param) throws Exception {
		this.param = param;
		final String lnf = MainManager.config.getProperty(CONF_STYLE);
		if (lnf != null) {
			for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if (info.getName().equals(lnf))
					try {
						UIManager.setLookAndFeel(info.getClassName());
					} catch (Exception ex) {
						MainManager.log.printException(ex);
					}
			}
			skins = SubstanceLookAndFeel.getAllSkins();
			if (skins.containsKey(lnf))
			{
				if(SwingUtilities.isEventDispatchThread()) {
					SubstanceLookAndFeel.setSkin(skins.get(lnf).getClassName());
				} else {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							SubstanceLookAndFeel.setSkin(skins.get(lnf).getClassName());
						}
					});
				}
			}
		}
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				JMenu LnFMenuItem = new JMenu("L&F");
				for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
					JMenuItem skinMenu = new JMenuItem(info.getName());
					skinMenu.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							try {
								UIManager.setLookAndFeel(info.getClassName());
								updateFrames();
								MainManager.config.setProperty(CONF_STYLE, info.getName());
								// report system, that style of user interface was changed
								LookAndFeelChanger.this.param.userInterface.addEvent(new UIEventChangeUIStyle());
							} catch (Exception ex) {
								MainManager.log.printException(ex);
								// throw new PluginException("Error while applying " + info.getName() + " skin",
								// EnumCriticalityException.ERROR);
							}
						}

					});
					LnFMenuItem.add(skinMenu);
				}
				LnFMenuItem.addSeparator();
				for (final String skin : SubstanceLookAndFeel.getAllSkins().keySet()) {
					JMenuItem skinMenu = new JMenuItem(skin);
					skinMenu.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.getAllSkins().get(skin).getClassName());
							updateFrames();
							MainManager.config.setProperty(CONF_STYLE, skin);
							LookAndFeelChanger.this.param.userInterface.addEvent(new UIEventChangeUIStyle());
						}
					});
					LnFMenuItem.add(skinMenu);
				}

				param.userInterface.addMenuItem(new AMenuItem(LnFMenuItem) {
					public void update(Observable o, Object arg) {
					}
				}, "window");
			}
		});
	}

	private void updateFrames() {
		Window[] localWindows = Window.getWindows();
		for (Window w : localWindows) {
			SwingUtilities.updateComponentTreeUI(w);
			// comment follow code, because it calls exception
			// if (w instanceof JFrame) {
			// Window frame = w;
			// boolean wasVisible = frame.isVisible();
			// frame.setVisible(false);
			// frame.dispose();
			// frame.setUndecorated(true);
			// if (UIManager.getLookAndFeel().getSupportsWindowDecorations()) {
			// frame.setUndecorated(true);
			// frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
			// } else {
			// frame.setUndecorated(false);
			// frame.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
			// }
			// frame.setVisible(wasVisible);
			// }
		}
	}
}
